package com.apes.scm.rbac.model;

import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.DefaultPersistListener;
import com.apes.framework.jpa.Model;
import com.apes.framework.jpa.Name;
import com.apes.framework.jpa.comment.Comment;
import com.apes.framework.jpa.generator.ApesGenerator;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.util.ApesConst;
import com.apes.framework.util.MapUtil;
import com.apes.hr.base.model.WorkPost;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.masterdata.frame.model.Branch;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.frame.model.Store;
import com.apes.scm.masterdata.frame.service.DeptService;
import com.apes.scm.masterdata.frame.service.StoreService;
import com.apes.scm.masterdata.party.model.AccessProvider;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.AccessProviderRepository;
import com.apes.scm.rbac.repository.LocalPermitItemRepository;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.SelectBeforeUpdate;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.*;

/**
 * 功能：岗位实体
 *
 * @author xul
 * @create 2017-12-15 11:09
 */

@Getter
@Setter
@SelectBeforeUpdate
@DynamicInsert
@DynamicUpdate
@Entity
@EntityListeners(DefaultPersistListener.class)
@Table(name = Post.CONST_TABLE_NAME, indexes = {@Index(name = "i_aut_posts_branch_post", columnList = "branch_id, work_post_id")})
public class Post extends Model {
    public static final String CONST_TABLE_NAME = "aut_posts";

    @Id
    @Column(name = "id")
    @ApesGenerator(code = CONST_TABLE_NAME, name = "岗位实体")
    private String id;

    @Column(name = "name")
    private String name;

    @Comment("商户管理层（0：非；1：是）")
    @Column(name = "merchant_management",nullable = false, columnDefinition= ApesConst.FIELD_BOOLEAN_FALSE)
    private boolean merchantManagement = false;

    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "company_id", referencedColumnName = "id", nullable = false)
    private PartyRole company; //公司

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "branch_id", referencedColumnName = "id")
    private Branch branch; //部门

    @Name
    @Transient
    private Map branchObj; //所属部门

    public Map getBranchObj() {
        if(branch == null) return null;
        return MapUtil.mapper("id",branch.getId(),"name",branch.getName(),"origin",branch.getOrigin());
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "work_post_id", referencedColumnName = "id")
    private WorkPost workPost; //行政岗位

    @ManyToMany(cascade = {CascadeType.MERGE},mappedBy="posts",fetch = FetchType.LAZY)
    private Set<User> assignedUsers;

    @Column(name = "ORIGIN", length = 20)
    private String origin; //外部ID

    @ManyToMany(cascade = {CascadeType.PERSIST,CascadeType.MERGE}, fetch = FetchType.LAZY)
    @JoinTable(name = "aut_role_posts",
            joinColumns = {@JoinColumn(name = "post_id", referencedColumnName = "id")},
            inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")}
    )
    private Set<Role> roles = new HashSet<>();

//    @ManyToMany(mappedBy = "assignedLocalPermits", fetch = FetchType.LAZY)
//    private Set<LocalPermit> localPermits = new HashSet<>();

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "local_permit_id", referencedColumnName = "id", nullable = false)
    private LocalPermit localPermit; //本地组织

    @Transient
    public List<Role> findAuthRoles() {
        Map<String, Role> results = new HashMap<>();
        findRole(results, getRoles());
        return new ArrayList(results.values());
    }

    @Transient
    private void findRole(Map<String, Role> results, Set<Role> roles) {
        roles.forEach(role -> {
            if (!results.containsKey(role.getId())) {
                results.put(role.getId(), role);
            }
            /**遍历继承角色**/
            Set<Role> parents = role.getDescendants();
            if (parents != null) {
                findRole(results, parents);
            }
        });
    }

    @Transient
    public List<Menu> findMenus(String terminal) {
        List<Role> roles = findAuthRoles();
        List<Menu> menus = new ArrayList<>();
        roles.forEach(role -> {
            menus.addAll(role.findMenus(terminal));
        });
        return menus;
    }

    @Name
    @Transient
    private Dept dept; //所属部门

    public Dept getDept() {
        if(localPermit == null) return null;
        try {
            LocalPermitItem localPermitItem = SpringManager.getBean(LocalPermitItemRepository.class).findAll(
                    JpaDsl.toCriteriaByEq(
                            "localPermit.id", localPermit.getId(),
                            "purpose.id", "pp_belong",
                            "type.id", "pt_dept"
                    )
            ).stream().findFirst().orElseGet(null);
            if(localPermitItem == null) return null;

            dept = SpringManager.getBean(DeptService.class).findOne(localPermitItem.getOrgId());
        } catch (Exception e) {
            dept = null;
        }
        return dept;
    }


    @Column(name = "ding_ding_dept_id")
    @Comment("钉钉部门id")
    private String dingDingDeptId;//钉钉部门id

    @Transient
    private Map accessProvider;

    public String getOperation() {
        if (!(this.company!=null&&this.company.getParty().getCorporate()!=null&&this.company.getParty().getCorporate().getOperation()!=null))return null;
        return this.company.getParty().getCorporate().getOperation().getId();
    }

    @Name
    @Transient
    private String operation;

    public String getPriLimitLevel() {
        if (workPost==null)return null;
        if (workPost.getPriLimitLevel()==null)return null;
        return workPost.getPriLimitLevel().getCode();
    }

    @Name
    @Transient
    private String priLimitLevel; //限价级别


    @Transient
    private boolean  qxEPCDeptFlag;
}
